home *** CD-ROM | disk | FTP | other *** search
/ PC Advisor 2010 April / PCA177.iso / ESSENTIALS / Firefox Setup.exe / nonlocalized / components / nsBrowserContentHandler.js < prev    next >
Encoding:
JavaScript  |  2009-07-15  |  32.3 KB  |  919 lines

  1. //@line 37 "e:\builds\moz2_slave\win32_build\build\browser\components\nsBrowserContentHandler.js"
  2.  
  3. const nsISupports            = Components.interfaces.nsISupports;
  4.  
  5. const nsIBrowserDOMWindow    = Components.interfaces.nsIBrowserDOMWindow;
  6. const nsIBrowserHandler      = Components.interfaces.nsIBrowserHandler;
  7. const nsIBrowserHistory      = Components.interfaces.nsIBrowserHistory;
  8. const nsIChannel             = Components.interfaces.nsIChannel;
  9. const nsICommandLine         = Components.interfaces.nsICommandLine;
  10. const nsICommandLineHandler  = Components.interfaces.nsICommandLineHandler;
  11. const nsIContentHandler      = Components.interfaces.nsIContentHandler;
  12. const nsIDocShellTreeItem    = Components.interfaces.nsIDocShellTreeItem;
  13. const nsIDOMChromeWindow     = Components.interfaces.nsIDOMChromeWindow;
  14. const nsIDOMWindow           = Components.interfaces.nsIDOMWindow;
  15. const nsIFactory             = Components.interfaces.nsIFactory;
  16. const nsIFileURL             = Components.interfaces.nsIFileURL;
  17. const nsIHttpProtocolHandler = Components.interfaces.nsIHttpProtocolHandler;
  18. const nsIInterfaceRequestor  = Components.interfaces.nsIInterfaceRequestor;
  19. const nsINetUtil             = Components.interfaces.nsINetUtil;
  20. const nsIPrefBranch          = Components.interfaces.nsIPrefBranch;
  21. const nsIPrefLocalizedString = Components.interfaces.nsIPrefLocalizedString;
  22. const nsISupportsString      = Components.interfaces.nsISupportsString;
  23. const nsIURIFixup            = Components.interfaces.nsIURIFixup;
  24. const nsIWebNavigation       = Components.interfaces.nsIWebNavigation;
  25. const nsIWindowMediator      = Components.interfaces.nsIWindowMediator;
  26. const nsIWindowWatcher       = Components.interfaces.nsIWindowWatcher;
  27. const nsICategoryManager     = Components.interfaces.nsICategoryManager;
  28. const nsIWebNavigationInfo   = Components.interfaces.nsIWebNavigationInfo;
  29. const nsIBrowserSearchService = Components.interfaces.nsIBrowserSearchService;
  30. const nsICommandLineValidator = Components.interfaces.nsICommandLineValidator;
  31.  
  32. const NS_BINDING_ABORTED = Components.results.NS_BINDING_ABORTED;
  33. const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
  34. const NS_ERROR_ABORT = Components.results.NS_ERROR_ABORT;
  35.  
  36. const URI_INHERITS_SECURITY_CONTEXT = nsIHttpProtocolHandler
  37.                                         .URI_INHERITS_SECURITY_CONTEXT;
  38.  
  39. function shouldLoadURI(aURI) {
  40.   if (aURI && !aURI.schemeIs("chrome"))
  41.     return true;
  42.  
  43.   dump("*** Preventing external load of chrome: URI into browser window\n");
  44.   dump("    Use -chrome <uri> instead\n");
  45.   return false;
  46. }
  47.  
  48. function resolveURIInternal(aCmdLine, aArgument) {
  49.   var uri = aCmdLine.resolveURI(aArgument);
  50.  
  51.   if (!(uri instanceof nsIFileURL)) {
  52.     return uri;
  53.   }
  54.  
  55.   try {
  56.     if (uri.file.exists())
  57.       return uri;
  58.   }
  59.   catch (e) {
  60.     Components.utils.reportError(e);
  61.   }
  62.  
  63.   // We have interpreted the argument as a relative file URI, but the file
  64.   // doesn't exist. Try URI fixup heuristics: see bug 290782.
  65.  
  66.   try {
  67.     var urifixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
  68.                              .getService(nsIURIFixup);
  69.  
  70.     uri = urifixup.createFixupURI(aArgument, 0);
  71.   }
  72.   catch (e) {
  73.     Components.utils.reportError(e);
  74.   }
  75.  
  76.   return uri;
  77. }
  78.  
  79. const OVERRIDE_NONE        = 0;
  80. const OVERRIDE_NEW_PROFILE = 1;
  81. const OVERRIDE_NEW_MSTONE  = 2;
  82. /**
  83.  * Determines whether a home page override is needed.
  84.  * Returns:
  85.  *  OVERRIDE_NEW_PROFILE if this is the first run with a new profile.
  86.  *  OVERRIDE_NEW_MSTONE if this is the first run with a build with a different
  87.  *                      Gecko milestone (i.e. right after an upgrade).
  88.  *  OVERRIDE_NONE otherwise.
  89.  */
  90. function needHomepageOverride(prefb) {
  91.   var savedmstone = null;
  92.   try {
  93.     savedmstone = prefb.getCharPref("browser.startup.homepage_override.mstone");
  94.   } catch (e) {}
  95.  
  96.   if (savedmstone == "ignore")
  97.     return OVERRIDE_NONE;
  98.  
  99.   var mstone = Components.classes["@mozilla.org/network/protocol;1?name=http"]
  100.                          .getService(nsIHttpProtocolHandler).misc;
  101.  
  102.   if (mstone != savedmstone) {
  103.     // Bug 462254. Previous releases had a default pref to suppress the EULA
  104.     // agreement if the platform's installer had already shown one. Now with
  105.     // about:rights we've removed the EULA stuff and default pref, but we need
  106.     // a way to make existing profiles retain the default that we removed.
  107.     if (savedmstone)
  108.       prefb.setBoolPref("browser.rights.3.shown", true);
  109.     
  110.     prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
  111.     return (savedmstone ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE);
  112.   }
  113.  
  114.   return OVERRIDE_NONE;
  115. }
  116.  
  117. // Copies a pref override file into the user's profile pref-override folder,
  118. // and then tells the pref service to reload its default prefs.
  119. function copyPrefOverride() {
  120.   try {
  121.     var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
  122.                                 .getService(Components.interfaces.nsIProperties);
  123.     const NS_APP_EXISTING_PREF_OVERRIDE = "ExistingPrefOverride";
  124.     var prefOverride = fileLocator.get(NS_APP_EXISTING_PREF_OVERRIDE,
  125.                                        Components.interfaces.nsIFile);
  126.     if (!prefOverride.exists())
  127.       return; // nothing to do
  128.  
  129.     const NS_APP_PREFS_OVERRIDE_DIR     = "PrefDOverride";
  130.     var prefOverridesDir = fileLocator.get(NS_APP_PREFS_OVERRIDE_DIR,
  131.                                            Components.interfaces.nsIFile);
  132.  
  133.     // Check for any existing pref overrides, and remove them if present
  134.     var existingPrefOverridesFile = prefOverridesDir.clone();
  135.     existingPrefOverridesFile.append(prefOverride.leafName);
  136.     if (existingPrefOverridesFile.exists())
  137.       existingPrefOverridesFile.remove(false);
  138.  
  139.     prefOverride.copyTo(prefOverridesDir, null);
  140.  
  141.     // Now that we've installed the new-profile pref override file,
  142.     // re-read the default prefs.
  143.     var prefSvcObs = Components.classes["@mozilla.org/preferences-service;1"]
  144.                                .getService(Components.interfaces.nsIObserver);
  145.     prefSvcObs.observe(null, "reload-default-prefs", null);
  146.   } catch (ex) {
  147.     Components.utils.reportError(ex);
  148.   }
  149. }
  150.  
  151. // Flag used to indicate that the arguments to openWindow can be passed directly.
  152. const NO_EXTERNAL_URIS = 1;
  153.  
  154. function openWindow(parent, url, target, features, args, noExternalArgs) {
  155.   var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
  156.                          .getService(nsIWindowWatcher);
  157.  
  158.   if (noExternalArgs == NO_EXTERNAL_URIS) {
  159.     // Just pass in the defaultArgs directly
  160.     var argstring;
  161.     if (args) {
  162.       argstring = Components.classes["@mozilla.org/supports-string;1"]
  163.                             .createInstance(nsISupportsString);
  164.       argstring.data = args;
  165.     }
  166.  
  167.     return wwatch.openWindow(parent, url, target, features, argstring);
  168.   }
  169.   
  170.   // Pass an array to avoid the browser "|"-splitting behavior.
  171.   var argArray = Components.classes["@mozilla.org/supports-array;1"]
  172.                     .createInstance(Components.interfaces.nsISupportsArray);
  173.  
  174.   // add args to the arguments array
  175.   var stringArgs = null;
  176.   if (args instanceof Array) // array
  177.     stringArgs = args;
  178.   else if (args) // string
  179.     stringArgs = [args];
  180.  
  181.   if (stringArgs) {
  182.     // put the URIs into argArray
  183.     var uriArray = Components.classes["@mozilla.org/supports-array;1"]
  184.                        .createInstance(Components.interfaces.nsISupportsArray);
  185.     stringArgs.forEach(function (uri) {
  186.       var sstring = Components.classes["@mozilla.org/supports-string;1"]
  187.                               .createInstance(nsISupportsString);
  188.       sstring.data = uri;
  189.       uriArray.AppendElement(sstring);
  190.     });
  191.     argArray.AppendElement(uriArray);
  192.   } else {
  193.     argArray.AppendElement(null);
  194.   }
  195.  
  196.   // Pass these as null to ensure that we always trigger the "single URL"
  197.   // behavior in browser.js's BrowserStartup (which handles the window
  198.   // arguments)
  199.   argArray.AppendElement(null); // charset
  200.   argArray.AppendElement(null); // referer
  201.   argArray.AppendElement(null); // postData
  202.   argArray.AppendElement(null); // allowThirdPartyFixup
  203.  
  204.   return wwatch.openWindow(parent, url, target, features, argArray);
  205. }
  206.  
  207. function openPreferences() {
  208.   var features = "chrome,titlebar,toolbar,centerscreen,dialog=no";
  209.   var url = "chrome://browser/content/preferences/preferences.xul";
  210.  
  211.   var win = getMostRecentWindow("Browser:Preferences");
  212.   if (win) {
  213.     win.focus();
  214.   } else {
  215.     openWindow(null, url, "_blank", features);
  216.   }
  217. }
  218.  
  219. function getMostRecentWindow(aType) {
  220.   var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  221.                      .getService(nsIWindowMediator);
  222.   return wm.getMostRecentWindow(aType);
  223. }
  224.  
  225. // this returns the most recent non-popup browser window
  226. function getMostRecentBrowserWindow() {
  227.   var browserGlue = Components.classes["@mozilla.org/browser/browserglue;1"]
  228.                               .getService(Components.interfaces.nsIBrowserGlue);
  229.   return browserGlue.getMostRecentBrowserWindow();
  230. }
  231.  
  232. function doSearch(searchTerm, cmdLine) {
  233.   var ss = Components.classes["@mozilla.org/browser/search-service;1"]
  234.                      .getService(nsIBrowserSearchService);
  235.  
  236.   var submission = ss.defaultEngine.getSubmission(searchTerm, null);
  237.  
  238.   // fill our nsISupportsArray with uri-as-wstring, null, null, postData
  239.   var sa = Components.classes["@mozilla.org/supports-array;1"]
  240.                      .createInstance(Components.interfaces.nsISupportsArray);
  241.  
  242.   var wuri = Components.classes["@mozilla.org/supports-string;1"]
  243.                        .createInstance(Components.interfaces.nsISupportsString);
  244.   wuri.data = submission.uri.spec;
  245.  
  246.   sa.AppendElement(wuri);
  247.   sa.AppendElement(null);
  248.   sa.AppendElement(null);
  249.   sa.AppendElement(submission.postData);
  250.  
  251.   // XXXbsmedberg: use handURIToExistingBrowser to obey tabbed-browsing
  252.   // preferences, but need nsIBrowserDOMWindow extensions
  253.  
  254.   var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
  255.                          .getService(nsIWindowWatcher);
  256.  
  257.   return wwatch.openWindow(null, nsBrowserContentHandler.chromeURL,
  258.                            "_blank",
  259.                            "chrome,dialog=no,all" +
  260.                              nsBrowserContentHandler.getFeatures(cmdLine),
  261.                            sa);
  262. }
  263.  
  264. var nsBrowserContentHandler = {
  265.   /* helper functions */
  266.  
  267.   mChromeURL : null,
  268.  
  269.   get chromeURL() {
  270.     if (this.mChromeURL) {
  271.       return this.mChromeURL;
  272.     }
  273.  
  274.     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
  275.                           .getService(nsIPrefBranch);
  276.     this.mChromeURL = prefb.getCharPref("browser.chromeURL");
  277.  
  278.     return this.mChromeURL;
  279.   },
  280.  
  281.   /* nsISupports */
  282.   QueryInterface : function bch_QI(iid) {
  283.     if (!iid.equals(nsISupports) &&
  284.         !iid.equals(nsICommandLineHandler) &&
  285.         !iid.equals(nsIBrowserHandler) &&
  286.         !iid.equals(nsIContentHandler) &&
  287.         !iid.equals(nsICommandLineValidator) &&
  288.         !iid.equals(nsIFactory))
  289.       throw Components.results.NS_ERROR_NO_INTERFACE;
  290.  
  291.     return this;
  292.   },
  293.  
  294.   /* nsICommandLineHandler */
  295.   handle : function bch_handle(cmdLine) {
  296.     if (cmdLine.handleFlag("browser", false)) {
  297.       // Passing defaultArgs, so use NO_EXTERNAL_URIS
  298.       openWindow(null, this.chromeURL, "_blank",
  299.                  "chrome,dialog=no,all" + this.getFeatures(cmdLine),
  300.                  this.defaultArgs, NO_EXTERNAL_URIS);
  301.       cmdLine.preventDefault = true;
  302.     }
  303.  
  304.     try {
  305.       var remoteCommand = cmdLine.handleFlagWithParam("remote", true);
  306.     }
  307.     catch (e) {
  308.       throw NS_ERROR_ABORT;
  309.     }
  310.  
  311.     if (remoteCommand != null) {
  312.       try {
  313.         var a = /^\s*(\w+)\(([^\)]*)\)\s*$/.exec(remoteCommand);
  314.         var remoteVerb;
  315.         if (a) {
  316.           remoteVerb = a[1].toLowerCase();
  317.           var remoteParams = [];
  318.           var sepIndex = a[2].lastIndexOf(",");
  319.           if (sepIndex == -1)
  320.             remoteParams[0] = a[2];
  321.           else {
  322.             remoteParams[0] = a[2].substring(0, sepIndex);
  323.             remoteParams[1] = a[2].substring(sepIndex + 1);
  324.           }
  325.         }
  326.  
  327.         switch (remoteVerb) {
  328.         case "openurl":
  329.         case "openfile":
  330.           // openURL(<url>)
  331.           // openURL(<url>,new-window)
  332.           // openURL(<url>,new-tab)
  333.  
  334.           // First param is the URL, second param (if present) is the "target"
  335.           // (tab, window)
  336.           var url = remoteParams[0];
  337.           var target = nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW;
  338.           if (remoteParams[1]) {
  339.             var targetParam = remoteParams[1].toLowerCase()
  340.                                              .replace(/^\s*|\s*$/g, "");
  341.             if (targetParam == "new-tab")
  342.               target = nsIBrowserDOMWindow.OPEN_NEWTAB;
  343.             else if (targetParam == "new-window")
  344.               target = nsIBrowserDOMWindow.OPEN_NEWWINDOW;
  345.             else {
  346.               // The "target" param isn't one of our supported values, so
  347.               // assume it's part of a URL that contains commas.
  348.               url += "," + remoteParams[1];
  349.             }
  350.           }
  351.  
  352.           var uri = resolveURIInternal(cmdLine, url);
  353.           handURIToExistingBrowser(uri, target, cmdLine);
  354.           break;
  355.  
  356.         case "xfedocommand":
  357.           // xfeDoCommand(openBrowser)
  358.           if (remoteParams[0].toLowerCase() != "openbrowser")
  359.             throw NS_ERROR_ABORT;
  360.  
  361.           // Passing defaultArgs, so use NO_EXTERNAL_URIS
  362.           openWindow(null, this.chromeURL, "_blank",
  363.                      "chrome,dialog=no,all" + this.getFeatures(cmdLine),
  364.                      this.defaultArgs, NO_EXTERNAL_URIS);
  365.           break;
  366.  
  367.         default:
  368.           // Somebody sent us a remote command we don't know how to process:
  369.           // just abort.
  370.           throw "Unknown remote command.";
  371.         }
  372.  
  373.         cmdLine.preventDefault = true;
  374.       }
  375.       catch (e) {
  376.         Components.utils.reportError(e);
  377.         // If we had a -remote flag but failed to process it, throw
  378.         // NS_ERROR_ABORT so that the xremote code knows to return a failure
  379.         // back to the handling code.
  380.         throw NS_ERROR_ABORT;
  381.       }
  382.     }
  383.  
  384.     var uriparam;
  385.     try {
  386.       while ((uriparam = cmdLine.handleFlagWithParam("new-window", false))) {
  387.         var uri = resolveURIInternal(cmdLine, uriparam);
  388.         if (!shouldLoadURI(uri))
  389.           continue;
  390.         openWindow(null, this.chromeURL, "_blank",
  391.                    "chrome,dialog=no,all" + this.getFeatures(cmdLine),
  392.                    uri.spec);
  393.         cmdLine.preventDefault = true;
  394.       }
  395.     }
  396.     catch (e) {
  397.       Components.utils.reportError(e);
  398.     }
  399.  
  400.     try {
  401.       while ((uriparam = cmdLine.handleFlagWithParam("new-tab", false))) {
  402.         var uri = resolveURIInternal(cmdLine, uriparam);
  403.         handURIToExistingBrowser(uri, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine);
  404.         cmdLine.preventDefault = true;
  405.       }
  406.     }
  407.     catch (e) {
  408.       Components.utils.reportError(e);
  409.     }
  410.  
  411.     var chromeParam = cmdLine.handleFlagWithParam("chrome", false);
  412.     if (chromeParam) {
  413.  
  414.       // Handle the old preference dialog URL separately (bug 285416)
  415.       if (chromeParam == "chrome://browser/content/pref/pref.xul") {
  416.         openPreferences();
  417.         cmdLine.preventDefault = true;
  418.       } else try {
  419.         // only load URIs which do not inherit chrome privs
  420.         var features = "chrome,dialog=no,all" + this.getFeatures(cmdLine);
  421.         var uri = resolveURIInternal(cmdLine, chromeParam);
  422.         var netutil = Components.classes["@mozilla.org/network/util;1"]
  423.                                 .getService(nsINetUtil);
  424.         if (!netutil.URIChainHasFlags(uri, URI_INHERITS_SECURITY_CONTEXT)) {
  425.           openWindow(null, uri.spec, "_blank", features);
  426.           cmdLine.preventDefault = true;
  427.         }
  428.       }
  429.       catch (e) {
  430.         Components.utils.reportError(e);
  431.       }
  432.     }
  433.     if (cmdLine.handleFlag("preferences", false)) {
  434.       openPreferences();
  435.       cmdLine.preventDefault = true;
  436.     }
  437.     if (cmdLine.handleFlag("silent", false))
  438.       cmdLine.preventDefault = true;
  439.  
  440.     var searchParam = cmdLine.handleFlagWithParam("search", false);
  441.     if (searchParam) {
  442.       doSearch(searchParam, cmdLine);
  443.       cmdLine.preventDefault = true;
  444.     }
  445.  
  446.     var fileParam = cmdLine.handleFlagWithParam("file", false);
  447.     if (fileParam) {
  448.       var file = cmdLine.resolveFile(fileParam);
  449.       var ios = Components.classes["@mozilla.org/network/io-service;1"]
  450.                           .getService(Components.interfaces.nsIIOService);
  451.       var uri = ios.newFileURI(file);
  452.       openWindow(null, this.chromeURL, "_blank", 
  453.                  "chrome,dialog=no,all" + this.getFeatures(cmdLine),
  454.                  uri.spec);
  455.       cmdLine.preventDefault = true;
  456.     }
  457.  
  458. //@line 494 "e:\builds\moz2_slave\win32_build\build\browser\components\nsBrowserContentHandler.js"
  459.     // Handle "? searchterm" for Windows Vista start menu integration
  460.     for (var i = cmdLine.length - 1; i >= 0; --i) {
  461.       var param = cmdLine.getArgument(i);
  462.       if (param.match(/^\? /)) {
  463.         cmdLine.removeArguments(i, i);
  464.         cmdLine.preventDefault = true;
  465.  
  466.         searchParam = param.substr(2);
  467.         doSearch(searchParam, cmdLine);
  468.       }
  469.     }
  470. //@line 506 "e:\builds\moz2_slave\win32_build\build\browser\components\nsBrowserContentHandler.js"
  471.   },
  472.  
  473.   helpInfo : "  -browser            Open a browser window.\n",
  474.  
  475.   /* nsIBrowserHandler */
  476.  
  477.   get defaultArgs() {
  478.     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
  479.                           .getService(nsIPrefBranch);
  480.     var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
  481.                               .getService(Components.interfaces.nsIURLFormatter);
  482.  
  483.     var overridePage = "";
  484.     var haveUpdateSession = false;
  485.     try {
  486.       switch (needHomepageOverride(prefb)) {
  487.         case OVERRIDE_NEW_PROFILE:
  488.           // New profile
  489.           overridePage = formatter.formatURLPref("startup.homepage_welcome_url");
  490.           break;
  491.         case OVERRIDE_NEW_MSTONE:
  492.           // Existing profile, new build
  493.           copyPrefOverride();
  494.  
  495.           // Check whether we have a session to restore. If we do, we assume
  496.           // that this is an "update" session.
  497.           var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
  498.                              .getService(Components.interfaces.nsISessionStartup);
  499.           haveUpdateSession = ss.doRestore();
  500.           overridePage = formatter.formatURLPref("startup.homepage_override_url");
  501.           break;
  502.     }
  503.     } catch (ex) {}
  504.  
  505.     // formatURLPref might return "about:blank" if getting the pref fails
  506.     if (overridePage == "about:blank")
  507.       overridePage = "";
  508.  
  509.     var startPage = "";
  510.     try {
  511.       var choice = prefb.getIntPref("browser.startup.page");
  512.       if (choice == 1 || choice == 3)
  513.         startPage = this.startPage;
  514.  
  515.       if (choice == 2)
  516.         startPage = Components.classes["@mozilla.org/browser/global-history;2"]
  517.                               .getService(nsIBrowserHistory).lastPageVisited;
  518.     } catch (e) {
  519.       Components.utils.reportError(e);
  520.     }
  521.  
  522.     if (startPage == "about:blank")
  523.       startPage = "";
  524.  
  525.     // Only show the startPage if we're not restoring an update session.
  526.     if (overridePage && startPage && !haveUpdateSession)
  527.       return overridePage + "|" + startPage;
  528.  
  529.     return overridePage || startPage || "about:blank";
  530.   },
  531.  
  532.   get startPage() {
  533.     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
  534.                           .getService(nsIPrefBranch);
  535.  
  536.     var uri = prefb.getComplexValue("browser.startup.homepage",
  537.                                     nsIPrefLocalizedString).data;
  538.  
  539.     if (!uri) {
  540.       prefb.clearUserPref("browser.startup.homepage");
  541.       uri = prefb.getComplexValue("browser.startup.homepage",
  542.                                   nsIPrefLocalizedString).data;
  543.     }
  544.                                 
  545.     var count;
  546.     try {
  547.       count = prefb.getIntPref("browser.startup.homepage.count");
  548.     }
  549.     catch (e) {
  550.       return uri;
  551.     }
  552.  
  553.     for (var i = 1; i < count; ++i) {
  554.       try {
  555.         var page = prefb.getComplexValue("browser.startup.homepage." + i,
  556.                                          nsIPrefLocalizedString).data;
  557.         uri += "\n" + page;
  558.       }
  559.       catch (e) {
  560.       }
  561.     }
  562.  
  563.     return uri;
  564.   },
  565.  
  566.   mFeatures : null,
  567.  
  568.   getFeatures : function bch_features(cmdLine) {
  569.     if (this.mFeatures === null) {
  570.       this.mFeatures = "";
  571.  
  572.       try {
  573.         var width = cmdLine.handleFlagWithParam("width", false);
  574.         var height = cmdLine.handleFlagWithParam("height", false);
  575.  
  576.         if (width)
  577.           this.mFeatures += ",width=" + width;
  578.         if (height)
  579.           this.mFeatures += ",height=" + height;
  580.       }
  581.       catch (e) {
  582.       }
  583.     }
  584.  
  585.     return this.mFeatures;
  586.   },
  587.  
  588.   /* nsIContentHandler */
  589.  
  590.   handleContent : function bch_handleContent(contentType, context, request) {
  591.     try {
  592.       var webNavInfo = Components.classes["@mozilla.org/webnavigation-info;1"]
  593.                                  .getService(nsIWebNavigationInfo);
  594.       if (!webNavInfo.isTypeSupported(contentType, null)) {
  595.         throw NS_ERROR_WONT_HANDLE_CONTENT;
  596.       }
  597.     } catch (e) {
  598.       throw NS_ERROR_WONT_HANDLE_CONTENT;
  599.     }
  600.  
  601.     request.QueryInterface(nsIChannel);
  602.     handURIToExistingBrowser(request.URI,
  603.       nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, null);
  604.     request.cancel(NS_BINDING_ABORTED);
  605.   },
  606.  
  607.   /* nsICommandLineValidator */
  608.   validate : function bch_validate(cmdLine) {
  609.     // Other handlers may use osint so only handle the osint flag if the url
  610.     // flag is also present and the command line is valid.
  611.     var osintFlagIdx = cmdLine.findFlag("osint", false);
  612.     var urlFlagIdx = cmdLine.findFlag("url", false);
  613.     if (urlFlagIdx > -1 && (osintFlagIdx > -1 ||
  614.         cmdLine.state == nsICommandLine.STATE_REMOTE_EXPLICIT)) {
  615.       var urlParam = cmdLine.getArgument(urlFlagIdx + 1);
  616.       if (cmdLine.length != urlFlagIdx + 2 || /firefoxurl:/.test(urlParam))
  617.         throw NS_ERROR_ABORT;
  618.       cmdLine.handleFlag("osint", false)
  619.     }
  620.   },
  621.  
  622.   /* nsIFactory */
  623.   createInstance: function bch_CI(outer, iid) {
  624.     if (outer != null)
  625.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  626.  
  627.     return this.QueryInterface(iid);
  628.   },
  629.     
  630.   lockFactory : function bch_lock(lock) {
  631.     /* no-op */
  632.   }
  633. };
  634.  
  635. const bch_contractID = "@mozilla.org/browser/clh;1";
  636. const bch_CID = Components.ID("{5d0ce354-df01-421a-83fb-7ead0990c24e}");
  637. const CONTRACTID_PREFIX = "@mozilla.org/uriloader/content-handler;1?type=";
  638.  
  639. function handURIToExistingBrowser(uri, location, cmdLine)
  640. {
  641.   if (!shouldLoadURI(uri))
  642.     return;
  643.  
  644.   var navWin = getMostRecentBrowserWindow();
  645.   if (!navWin) {
  646.     // if we couldn't load it in an existing window, open a new one
  647.     openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
  648.                "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
  649.                uri.spec);
  650.     return;
  651.   }
  652.  
  653.   var navNav = navWin.QueryInterface(nsIInterfaceRequestor)
  654.                      .getInterface(nsIWebNavigation);
  655.   var rootItem = navNav.QueryInterface(nsIDocShellTreeItem).rootTreeItem;
  656.   var rootWin = rootItem.QueryInterface(nsIInterfaceRequestor)
  657.                         .getInterface(nsIDOMWindow);
  658.   var bwin = rootWin.QueryInterface(nsIDOMChromeWindow).browserDOMWindow;
  659.   bwin.openURI(uri, null, location,
  660.                nsIBrowserDOMWindow.OPEN_EXTERNAL);
  661. }
  662.  
  663.  
  664. var nsDefaultCommandLineHandler = {
  665.   /* nsISupports */
  666.   QueryInterface : function dch_QI(iid) {
  667.     if (!iid.equals(nsISupports) &&
  668.         !iid.equals(nsICommandLineHandler) &&
  669.         !iid.equals(nsIFactory))
  670.       throw Components.results.NS_ERROR_NO_INTERFACE;
  671.  
  672.     return this;
  673.   },
  674.  
  675.   // List of uri's that were passed via the command line without the app
  676.   // running and have already been handled. This is compared against uri's
  677.   // opened using DDE on Win32 so we only open one of the requests.
  678.   _handledURIs: [ ],
  679. //@line 715 "e:\builds\moz2_slave\win32_build\build\browser\components\nsBrowserContentHandler.js"
  680.   _haveProfile: false,
  681. //@line 717 "e:\builds\moz2_slave\win32_build\build\browser\components\nsBrowserContentHandler.js"
  682.  
  683.   /* nsICommandLineHandler */
  684.   handle : function dch_handle(cmdLine) {
  685.     var urilist = [];
  686.  
  687. //@line 723 "e:\builds\moz2_slave\win32_build\build\browser\components\nsBrowserContentHandler.js"
  688.     // If we don't have a profile selected yet (e.g. the Profile Manager is
  689.     // displayed) we will crash if we open an url and then select a profile. To
  690.     // prevent this handle all url command line flags and set the command line's
  691.     // preventDefault to true to prevent the display of the ui. The initial
  692.     // command line will be retained when nsAppRunner calls LaunchChild though
  693.     // urls launched after the initial launch will be lost.
  694.     if (!this._haveProfile) {
  695.       try {
  696.         // This will throw when a profile has not been selected.
  697.         var fl = Components.classes["@mozilla.org/file/directory_service;1"]
  698.                            .getService(Components.interfaces.nsIProperties);
  699.         var dir = fl.get("ProfD", Components.interfaces.nsILocalFile);
  700.         this._haveProfile = true;
  701.       }
  702.       catch (e) {
  703.         while ((ar = cmdLine.handleFlagWithParam("url", false))) { }
  704.         cmdLine.preventDefault = true;
  705.       }
  706.     }
  707. //@line 743 "e:\builds\moz2_slave\win32_build\build\browser\components\nsBrowserContentHandler.js"
  708.  
  709.     try {
  710.       var ar;
  711.       while ((ar = cmdLine.handleFlagWithParam("url", false))) {
  712.         var found = false;
  713.         var uri = resolveURIInternal(cmdLine, ar);
  714.         // count will never be greater than zero except on Win32.
  715.         var count = this._handledURIs.length;
  716.         for (var i = 0; i < count; ++i) {
  717.           if (this._handledURIs[i].spec == uri.spec) {
  718.             this._handledURIs.splice(i, 1);
  719.             found = true;
  720.             cmdLine.preventDefault = true;
  721.             break;
  722.           }
  723.         }
  724.         if (!found) {
  725.           urilist.push(uri);
  726.           // The requestpending command line flag is only used on Win32.
  727.           if (cmdLine.handleFlag("requestpending", false) &&
  728.               cmdLine.state == nsICommandLine.STATE_INITIAL_LAUNCH)
  729.             this._handledURIs.push(uri)
  730.         }
  731.       }
  732.     }
  733.     catch (e) {
  734.       Components.utils.reportError(e);
  735.     }
  736.  
  737.     count = cmdLine.length;
  738.  
  739.     for (i = 0; i < count; ++i) {
  740.       var curarg = cmdLine.getArgument(i);
  741.       if (curarg.match(/^-/)) {
  742.         Components.utils.reportError("Warning: unrecognized command line flag " + curarg + "\n");
  743.         // To emulate the pre-nsICommandLine behavior, we ignore
  744.         // the argument after an unrecognized flag.
  745.         ++i;
  746.       } else {
  747.         try {
  748.           urilist.push(resolveURIInternal(cmdLine, curarg));
  749.         }
  750.         catch (e) {
  751.           Components.utils.reportError("Error opening URI '" + curarg + "' from the command line: " + e + "\n");
  752.         }
  753.       }
  754.     }
  755.  
  756.     if (urilist.length) {
  757.       if (cmdLine.state != nsICommandLine.STATE_INITIAL_LAUNCH &&
  758.           urilist.length == 1) {
  759.         // Try to find an existing window and load our URI into the
  760.         // current tab, new tab, or new window as prefs determine.
  761.         try {
  762.           handURIToExistingBrowser(urilist[0], nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, cmdLine);
  763.           return;
  764.         }
  765.         catch (e) {
  766.         }
  767.       }
  768.  
  769.       var URLlist = urilist.filter(shouldLoadURI).map(function (u) u.spec);
  770.       if (URLlist.length) {
  771.         openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
  772.                    "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
  773.                    URLlist);
  774.       }
  775.  
  776.     }
  777.     else if (!cmdLine.preventDefault) {
  778.       // Passing defaultArgs, so use NO_EXTERNAL_URIS
  779.       openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
  780.                  "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
  781.                  nsBrowserContentHandler.defaultArgs, NO_EXTERNAL_URIS);
  782.     }
  783.   },
  784.  
  785.   // XXX localize me... how?
  786.   helpInfo : "Usage: firefox [-flags] [<url>]\n",
  787.  
  788.   /* nsIFactory */
  789.   createInstance: function dch_CI(outer, iid) {
  790.     if (outer != null)
  791.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  792.  
  793.     return this.QueryInterface(iid);
  794.   },
  795.     
  796.   lockFactory : function dch_lock(lock) {
  797.     /* no-op */
  798.   }
  799. };
  800.  
  801. const dch_contractID = "@mozilla.org/browser/final-clh;1";
  802. const dch_CID = Components.ID("{47cd0651-b1be-4a0f-b5c4-10e5a573ef71}");
  803.  
  804. var Module = {
  805.   /* nsISupports */
  806.   QueryInterface: function mod_QI(iid) {
  807.     if (iid.equals(Components.interfaces.nsIModule) ||
  808.         iid.equals(Components.interfaces.nsISupports))
  809.       return this;
  810.  
  811.     throw Components.results.NS_ERROR_NO_INTERFACE;
  812.   },
  813.  
  814.   /* nsIModule */
  815.   getClassObject: function mod_getco(compMgr, cid, iid) {
  816.     if (cid.equals(bch_CID))
  817.       return nsBrowserContentHandler.QueryInterface(iid);
  818.  
  819.     if (cid.equals(dch_CID))
  820.       return nsDefaultCommandLineHandler.QueryInterface(iid);
  821.  
  822.     throw Components.results.NS_ERROR_NO_INTERFACE;
  823.   },
  824.     
  825.   registerSelf: function mod_regself(compMgr, fileSpec, location, type) {
  826.     if (Components.classes["@mozilla.org/xre/app-info;1"]) {
  827.       // Don't register these if Firefox is launching a XULRunner application
  828.       const FIREFOX_UID = "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
  829.       var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
  830.                               .getService(Components.interfaces.nsIXULAppInfo);
  831.       if (appInfo.ID != FIREFOX_UID)
  832.         return;
  833.     }
  834.  
  835.     var compReg =
  836.       compMgr.QueryInterface( Components.interfaces.nsIComponentRegistrar );
  837.  
  838.     compReg.registerFactoryLocation( bch_CID,
  839.                                      "nsBrowserContentHandler",
  840.                                      bch_contractID,
  841.                                      fileSpec,
  842.                                      location,
  843.                                      type );
  844.     compReg.registerFactoryLocation( dch_CID,
  845.                                      "nsDefaultCommandLineHandler",
  846.                                      dch_contractID,
  847.                                      fileSpec,
  848.                                      location,
  849.                                      type );
  850.  
  851.     function registerType(contentType) {
  852.       compReg.registerFactoryLocation( bch_CID,
  853.                                        "Browser Cmdline Handler",
  854.                                        CONTRACTID_PREFIX + contentType,
  855.                                        fileSpec,
  856.                                        location,
  857.                                        type );
  858.     }
  859.  
  860.     registerType("text/html");
  861.     registerType("application/vnd.mozilla.xul+xml");
  862. //@line 898 "e:\builds\moz2_slave\win32_build\build\browser\components\nsBrowserContentHandler.js"
  863.     registerType("image/svg+xml");
  864. //@line 900 "e:\builds\moz2_slave\win32_build\build\browser\components\nsBrowserContentHandler.js"
  865.     registerType("text/rdf");
  866.     registerType("text/xml");
  867.     registerType("application/xhtml+xml");
  868.     registerType("text/css");
  869.     registerType("text/plain");
  870.     registerType("image/gif");
  871.     registerType("image/jpeg");
  872.     registerType("image/jpg");
  873.     registerType("image/png");
  874.     registerType("image/bmp");
  875.     registerType("image/x-icon");
  876.     registerType("image/vnd.microsoft.icon");
  877.     registerType("image/x-xbitmap");
  878.     registerType("application/http-index-format");
  879.  
  880.     var catMan = Components.classes["@mozilla.org/categorymanager;1"]
  881.                            .getService(nsICategoryManager);
  882.  
  883.     catMan.addCategoryEntry("command-line-handler",
  884.                             "m-browser",
  885.                             bch_contractID, true, true);
  886.     catMan.addCategoryEntry("command-line-handler",
  887.                             "x-default",
  888.                             dch_contractID, true, true);
  889.     catMan.addCategoryEntry("command-line-validator",
  890.                             "b-browser",
  891.                             bch_contractID, true, true);
  892.   },
  893.     
  894.   unregisterSelf : function mod_unregself(compMgr, location, type) {
  895.     var compReg = compMgr.QueryInterface(nsIComponentRegistrar);
  896.     compReg.unregisterFactoryLocation(bch_CID, location);
  897.     compReg.unregisterFactoryLocation(dch_CID, location);
  898.  
  899.     var catMan = Components.classes["@mozilla.org/categorymanager;1"]
  900.                            .getService(nsICategoryManager);
  901.  
  902.     catMan.deleteCategoryEntry("command-line-handler",
  903.                                "m-browser", true);
  904.     catMan.deleteCategoryEntry("command-line-handler",
  905.                                "x-default", true);
  906.     catMan.deleteCategoryEntry("command-line-validator",
  907.                                "b-browser", true);
  908.   },
  909.  
  910.   canUnload: function(compMgr) {
  911.     return true;
  912.   }
  913. };
  914.  
  915. // NSGetModule: Return the nsIModule object.
  916. function NSGetModule(compMgr, fileSpec) {
  917.   return Module;
  918. }
  919.